package com.baor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baor.dao.MenuDao;
import com.baor.dao.RoleDao;
import com.baor.dao.RoleMenuDao;
import com.baor.dao.UserDao;
import com.baor.domain.*;
import com.baor.service.RoleService;
import com.baor.utils.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.baor.utils.DateUtil.now;


@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private RoleMenuDao roleMenuDao;

    @Autowired
    private MenuDao menuDao;

    @Autowired
    private UserDao userDao;


    @Override
    public AjaxResult<?> roleList(RoleVo vo) {
        Page<RoleVo> page = null;
        Map<String,Object> map = new HashMap<>();
        if(vo.getPageIndex() != null){
            page = new Page<>(vo.getPageIndex(),vo.getPageSize());
        }else{
            page = new Page<>(1,10);
        }
        LambdaQueryWrapper<RoleVo> lqw = new LambdaQueryWrapper<>();
        lqw.notIn(RoleVo::getRoleId, 1);
        map.put("pageCount", roleDao.selectPage(page, lqw).getPages());
        map.put("list", roleDao.selectPage(page, lqw).getRecords());
        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult<?> insert(RoleVo roleVo) {
        roleVo.setRoleCreatetime(now());
        return roleDao.insert(roleVo) > 0 ? AjaxResult.success(roleVo.getRoleId()) : AjaxResult.error("插入失败") ;
    }

    @Override
    public AjaxResult<?> update(RoleVo roleVo) {
        return roleDao.updateById(roleVo) > 0 ? AjaxResult.success(roleVo.getRoleId()) : AjaxResult.error("更新失败") ;
    }

    @Override
    public AjaxResult<?> delete(Integer roleId) {
        Map<String,Object> map = new HashMap<>();
        map.put("roleId",roleId);
        Integer roleId2 = roleDao.selectList(new LambdaQueryWrapper<RoleVo>().ne(RoleVo::getRoleId,roleId).orderByDesc(RoleVo::getRoleId)).get(0).getRoleId();
        map.put("roleId2",roleId2);
        List<Integer> integers = userDao.selectList(new LambdaQueryWrapper<UserVo>().eq(UserVo::getUserRole, roleId)).stream().map(x -> x.getUserId()).collect(Collectors.toList());
        System.out.println(integers);
        Integer i = userDao.updateRole(map);
        roleMenuDao.deleteById(roleId);
        return roleDao.deleteById(roleId) > 0 ? AjaxResult.success("删除权限后，以下用户身份受到变化",integers) : AjaxResult.error("删除失败") ;
    }


    @Override
    public AjaxResult<?> search(RoleVo vo) {
        LambdaQueryWrapper<RoleVo> lqw = new LambdaQueryWrapper<>();
        lqw.notIn(RoleVo::getRoleId, 1);
        Page<RoleVo> page = null;
        Map<String,Object> map = new HashMap<>();
        if(vo.getPageIndex() != null && vo.getRoleName() != null){
            lqw.like(RoleVo::getRoleName, vo.getRoleName());
            page = new Page<>(vo.getPageIndex(),vo.getPageSize());
            map.put("list", roleDao.selectPage(page,lqw).getRecords());
            map.put("pageCount", roleDao.selectPage(page, lqw).getPages());
        } else if (vo.getRoleName() != null) {
            lqw.like(RoleVo::getRoleName, vo.getRoleName());
            page = new Page<>(1,10);
            map.put("list", roleDao.selectPage(page,lqw).getRecords());
            map.put("pageCount", roleDao.selectPage(page, lqw).getPages());
        }else if(vo.getPageIndex() != null){
            page = new Page<>(vo.getPageIndex(),vo.getPageSize());
            map.put("list", roleDao.selectPage(page,null).getRecords());
            map.put("pageCount", roleDao.selectPage(page, null).getPages());
        }else{
            page = new Page<>(1,10);
            map.put("list", roleDao.selectPage(page,null).getRecords());
            map.put("pageCount", roleDao.selectPage(page, null).getPages());
        }
        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult<?> chooseMenu(Map<String, Object> map) {
        Integer roleId = Integer.valueOf(map.get("roleId").toString());
        List<Integer> menuIds = (List<Integer>) map.get("menuIds");
        for ( Integer menuId : menuIds ){
            getParents(menuId,roleId);
        }
        return AjaxResult.success();
    }

    private void getParents(Integer menuId,Integer roleId) {
        MenuVo menuVo = menuDao.selectById(menuId);
        if ( menuVo.getMenuSuperiors() != null )
            getParents(menuVo.getMenuSuperiors(),roleId);
        roleMenuDao.insert(new RoleMenuVo(menuId,roleId));
    }

    @Override
    public AjaxResult<?> info(Integer roleId) {
        return AjaxResult.success(roleDao.selectById(roleId));
    }

    @Override
    public AjaxResult<?> getMenu(Integer roleId) {
        List<RoleMenuVo> roleMenuVos = roleMenuDao.selectList(new LambdaQueryWrapper<RoleMenuVo>().eq(RoleMenuVo::getRoleId, roleId));
        if ( roleMenuVos.size() == 0 )
            return AjaxResult.error("该身份无权限，请为其分配权限");
        List<MenuVo> menuVos = menuDao.selectList(new LambdaQueryWrapper<MenuVo>().in(MenuVo::getMenuId, roleMenuVos.stream().map(x -> x.getMenuId()).collect(Collectors.toList())));
        return AjaxResult.success(menuVos);
    }

    @Override
    public AjaxResult<?> getMenus(Integer roleId) {
        List<RoleMenuVo> roleMenuVos = roleMenuDao.selectList(new LambdaQueryWrapper<RoleMenuVo>().eq(RoleMenuVo::getRoleId, roleId));
        if ( roleMenuVos.size() == 0 )
            return AjaxResult.error("该身份无权限，请为其分配权限");
        List<MenuVo> parents = menuDao.selectList(new LambdaQueryWrapper<MenuVo>().in(MenuVo::getMenuId, roleMenuVos.stream().map(x -> x.getMenuId()).collect(Collectors.toList())));
        List<MenuVo> list = new ArrayList<>();
        for ( MenuVo vo : parents ){
            if ( vo.getMenuSuperiors() != null )
                break;
            vo.setChilds(getChild(vo.getMenuId(),parents));
            list.add(vo);
        }
        return AjaxResult.success(list);
    }

    private List<MenuVo> getChild(Integer menuId, List<MenuVo> target){
        List<MenuVo> childs = target.stream().filter(x -> menuId.equals(x.getMenuSuperiors())).collect(Collectors.toList());
        if ( childs.size() != 0 )
            childs.forEach( x -> x.setChilds(getChild(x.getMenuId(),target)) );
        return childs;
    }

    @Override
    public AjaxResult<?> updateMenus(Map<String, Object> map) {
        Integer roleId = Integer.valueOf(map.get("roleId").toString());
        List<Integer> menuIds = (List<Integer>) map.get("menuIds");
        roleMenuDao.delete(new LambdaUpdateWrapper<RoleMenuVo>().eq(RoleMenuVo::getRoleId,roleId));
        for ( Integer menuId : menuIds )
            getParents(menuId,roleId);
        return AjaxResult.success();
    }


    @Override
    public AjaxResult<?> deleteMenus(Integer roleId) {
        roleMenuDao.delete(new LambdaUpdateWrapper<RoleMenuVo>().eq(RoleMenuVo::getRoleId,roleId));
        return AjaxResult.success();
    }

}
